﻿using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using ShenNius.Repository;
using ShenNius.Repository.Extensions;
using ShenNius.Sys.API.Domain.Entity;
using ShenNius.Sys.API.Domain.Repository;
using ShenNius.Sys.API.Dtos.Common;
using ShenNius.Sys.API.Dtos.Input;
using ShenNius.Sys.API.Dtos.Output;
using ShenNius.Sys.API.Infrastructure.Attributes;
using ShenNius.Sys.API.Infrastructure.Configs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace ShenNius.Sys.API.Controllers
{
    public class RoleController : ApiControllerBase
    {
        private readonly IBaseRepository<Role> _roleRepository;
        private readonly IBaseRepository<R_User_Role> _r_User_roleRepository;
        private readonly IRecycleRepository _recycleRepository;
        private readonly IMapper _mapper;
        private readonly IBaseRepository<R_Role_Menu> _r_Role_MenuRepository;

        public RoleController(IBaseRepository<Role> roleRepository, IMapper mapper, IBaseRepository<R_Role_Menu> r_Role_MenuRepository, IBaseRepository<R_User_Role> r_User_roleRepository, IRecycleRepository recycleRepository)
        {
            _roleRepository = roleRepository;
            _mapper = mapper;
            _r_Role_MenuRepository = r_Role_MenuRepository;
            _r_User_roleRepository = r_User_roleRepository;
            _recycleRepository = recycleRepository;
        }
        [HttpDelete, Authority]
        public async Task<ApiResult> Deletes([FromBody] DeletesInput commonDeleteInput)
        {
            return new ApiResult(await _roleRepository.DeleteAsync(commonDeleteInput.Ids));
        }

        [HttpDelete, Authority(Action = nameof(Button.Delete))]
        public virtual Task<ApiResult> SoftDelete([FromBody] DeletesInput deleteInput)
        {
            return _recycleRepository.SoftDeleteAsync(deleteInput, _roleRepository);
        }
        [HttpGet, Authority]
        public async Task<ApiResult> GetListPages(int page, int limit = 15, string key = null)
        {
            Expression<Func<Role, bool>> whereExpression = d => !d.IsDeleted;
            if (!string.IsNullOrEmpty(key))
            {
                whereExpression = d => d.Name.Contains(key) && !d.IsDeleted;
            }
            var res = await _roleRepository.GetPagesAsync(page, limit, whereExpression, d => d.Id, false);
            return new ApiResult(data: new { count = res.TotalItems, items = res.Items });
        }
        /// <summary>
        /// 根据角色获取当前已授权或未授权的所有角色
        /// </summary>
        /// <param name="page">当前页</param>
        /// <param name="userId"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> GetListPagesByUser(int userId, int page = 1, int limit = 15)
        {
            var query = await _roleRepository.GetPagesAsync(page, limit, d => d.IsDeleted == false, true);
            var allRole = _mapper.Map<Page<RoleOutput>>(query);
            var userRoleList = await _r_User_roleRepository.GetListAsync(d => d.UserId == userId && d.IsDeleted == false);
            foreach (var item in allRole.Items)
            {
                var model = userRoleList.FirstOrDefault(d => d.RoleId == item.Id);
                item.Status = model != null;
            }
            return new ApiResult(data: new { count = query.TotalItems, items = query.Items });
        }
        [HttpGet, Authority]
        public async Task<ApiResult> Detail(int id)
        {
            if (id == 0)
            {
                throw new ArgumentException(nameof(id));
            }
            var res = await _roleRepository.GetModelAsync(d => d.Id == id && d.IsDeleted == false);
            return new ApiResult(data: res);
        }
        [HttpGet]
        public async Task<ApiResult> List()
        {
            var data = await _roleRepository.GetListAsync(d => d.IsDeleted == false);
            return new ApiResult(data: data);
        }

        [HttpPost, Authority]
        public async Task<ApiResult> Add([FromBody] RoleInput input)
        {
            var model = await _roleRepository.GetModelAsync(d => !d.IsDeleted && d.Name.Equals(input.Name));
            if (model != null && model.Id > 0)
            {
                return new ApiResult($"已经存在[{input.Name}]该角色了");
            }
            var role = _mapper.Map<Role>(input);
            return new ApiResult(await _roleRepository.AddAsync(role));
        }

        [HttpPost, Authority(Action = nameof(Button.Auth))]
        public async Task<ApiResult> SetMenu(SetRoleMenuInput setRoleMenuInput)
        {
            var allUserMenus = await _r_Role_MenuRepository.GetListAsync(d => d.IsDeleted == false);
            // allUserRoles.Where(d => d.UserId == setUserRoleInput.UserId && setUserRoleInput.RoleIds.Contains(d.RoleId));
            List<R_Role_Menu> list = new List<R_Role_Menu>();
            foreach (var item in setRoleMenuInput.MenuIds)
            {
                var model = allUserMenus.Where(d => d.RoleId == setRoleMenuInput.RoleId && d.MenuId == item);
                if (model == null)
                {
                    var r_User_Menu = R_Role_Menu.Create(setRoleMenuInput.RoleId, item);
                    list.Add(r_User_Menu);
                    //add                    
                }
            }
            var i = await _r_Role_MenuRepository.AddListAsync(list);
            return i > 0 ? new ApiResult() : new ApiResult("设置菜单失败了！");
        }

        [HttpPut, Authority]
        public async Task<ApiResult> Modify([FromBody] RoleModifyInput input)
        {
            var isExistNamemodel = await _roleRepository.GetModelAsync(d => !d.IsDeleted && d.Id != input.Id && d.Name.Equals(input.Name));
            if (isExistNamemodel != null && isExistNamemodel.Id > 0)
            {
                return new ApiResult($"已经存在[{input.Name}]该角色了");
            }
            var model = await _roleRepository.GetModelAsync(d => !d.IsDeleted && d.Id == input.Id);
            if (model == null && model.Id <= 0)
            {
                return new ApiResult($"不存在[{input.Id}]该条数据");
            }
            model.Modify(input.Id, input.Name, input.Description);
            await _roleRepository.UpdateAsync(model, d => new { d.CreateTime, d.DeleteTime, d.IsDeleted });
            return new ApiResult();
        }
    }
}
